排序算法——二路归并排序

二路归并排序主要运用了“分治算法”,分治算法就是将一个大的问题划分为n个规模较小而结构相似的子问题。

这些子问题解决的方法都是类似的,解决掉这些小的问题之后,归并子问题的结果,就得到了“大”问题的解。

二路归并排序主旨是“分解”与“归并”。

下面是参考《高性能JavaScript》中的代码:

 function merge(left, right) {  
    var result = [];  
    while(left.length > 0 && right.length > 0) {  
       if(left[0] < right[0]) {  
           result.push(left.shift());  
       }  
       else {  
           result.push(right.shift());  
       }  
   }  

   return result.concat(left).concat(right);  
}  
    function mergeSort(arr){  
        if(arr.length==1) {return arr};  
        var mid=Math.floor(arr.length/2);  
        var left_arr=arr.slice(0,mid),right_arr=arr.slice(mid);  
        return merge(mergeSort(left_arr),mergeSort(right_arr));  
    }  

这段代码很简单易懂,但是容易出现栈溢出错误。此时我们可以更改mergeSort()函数,用迭代的方式来实现,代码如下所示:

 

function mergeSort(items){
    if(items.length==1){
          return items;  
    }
    var work=[];
    for(var i=0;len=items.length;i<len;i++){
        work.push([items[i]]);    
     }      
      work.push([]); //如果数组长度为奇数
      for(var lim=len;lim>1;lim=(lim+1)/2){
          for(var j=0,k=0;k<lim;j++,k+=2){
               work[j]=merge(work[k],work[k+1]);
          }
           work[j]=[]; //如果数组为奇数
      }    
      return work[0];          

}            

 

这个版本中的mergeSort()函数功能与前例相同,但是没有使用递归。把递归算法改用迭代实现是避免栈溢出的错误方法之一。

 

posted @ 2017-08-04 22:31  入门级小菜  阅读(1613)  评论(0编辑  收藏  举报